home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / Mesa-3.0 / 3Dfx / DEMOS / IMAGE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-06-20  |  5.0 KB  |  233 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h> 
  4. #include <GL/glut.h>
  5. #include "image.h"
  6.  
  7. #define IMAGIC      0x01da
  8. #define IMAGIC_SWAP 0xda01
  9.  
  10. #define SWAP_SHORT_BYTES(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8))
  11. #define SWAP_LONG_BYTES(x) (((((x) & 0xff) << 24) | (((x) & 0xff00) << 8)) | \
  12. ((((x) & 0xff0000) >> 8) | (((x) & 0xff000000) >> 24)))
  13.  
  14.      typedef struct  
  15.      {
  16.        unsigned short imagic;
  17.        unsigned short type;
  18.        unsigned short dim;
  19.        unsigned short sizeX, sizeY, sizeZ;
  20.        unsigned long min, max;
  21.        unsigned long wasteBytes;
  22.        char name[80];
  23.        unsigned long colorMap;
  24.        FILE *file;
  25.        unsigned char *tmp[5];
  26.        unsigned long rleEnd;
  27.        unsigned long *rowStart;
  28.        unsigned long *rowSize;
  29.      } Image;
  30.  
  31.  
  32. static Image *ImageOpen(char *fileName)
  33. {
  34.   Image *image;
  35.   unsigned long *rowStart, *rowSize, ulTmp;
  36.   int x, i;
  37.  
  38.   image = (Image *)malloc(sizeof(Image));
  39.   if (image == NULL) 
  40.     {
  41.       fprintf(stderr, "Out of memory!\n");
  42.       exit(-1);
  43.     }
  44.   if ((image->file = fopen(fileName, "rb")) == NULL) 
  45.     {
  46.       perror(fileName);
  47.       exit(-1);
  48.     }
  49.   /*
  50.    *    Read the image header
  51.    */
  52.   fread(image, 1, 12, image->file);
  53.   /*
  54.    *    Check byte order
  55.    */
  56.   if (image->imagic == IMAGIC_SWAP) 
  57.     {
  58.       image->type = SWAP_SHORT_BYTES(image->type);
  59.       image->dim = SWAP_SHORT_BYTES(image->dim);
  60.       image->sizeX = SWAP_SHORT_BYTES(image->sizeX);
  61.       image->sizeY = SWAP_SHORT_BYTES(image->sizeY);
  62.       image->sizeZ = SWAP_SHORT_BYTES(image->sizeZ);
  63.     }
  64.  
  65.   for ( i = 0 ; i <= image->sizeZ ; i++ )
  66.     {
  67.       image->tmp[i] = (unsigned char *)malloc(image->sizeX*256);
  68.       if (image->tmp[i] == NULL ) 
  69.     {
  70.       fprintf(stderr, "Out of memory!\n");
  71.       exit(-1);
  72.     }
  73.     }
  74.  
  75.   if ((image->type & 0xFF00) == 0x0100) /* RLE image */
  76.     {
  77.       x = image->sizeY * image->sizeZ * sizeof(long);
  78.       image->rowStart = (unsigned long *)malloc(x);
  79.       image->rowSize = (unsigned long *)malloc(x);
  80.       if (image->rowStart == NULL || image->rowSize == NULL) 
  81.     {
  82.       fprintf(stderr, "Out of memory!\n");
  83.       exit(-1);
  84.     }
  85.       image->rleEnd = 512 + (2 * x);
  86.       fseek(image->file, 512, SEEK_SET);
  87.       fread(image->rowStart, 1, x, image->file);
  88.       fread(image->rowSize, 1, x, image->file);
  89.       if (image->imagic == IMAGIC_SWAP) 
  90.     {
  91.       x /= sizeof(long);
  92.       rowStart = image->rowStart;
  93.       rowSize = image->rowSize;
  94.       while (x--) 
  95.         {
  96.           ulTmp = *rowStart;
  97.           *rowStart++ = SWAP_LONG_BYTES(ulTmp);
  98.           ulTmp = *rowSize;
  99.           *rowSize++ = SWAP_LONG_BYTES(ulTmp);
  100.         }
  101.     }
  102.     }
  103.   return image;
  104. }
  105.  
  106. static void ImageClose( Image *image)
  107. {
  108.   int i;
  109.  
  110.   fclose(image->file);
  111.   for ( i = 0 ; i <= image->sizeZ ; i++ )
  112.     free(image->tmp[i]);
  113.   free(image);
  114. }
  115.  
  116. static void ImageGetRow( Image *image, unsigned char *buf, int y, int z)
  117. {
  118.   unsigned char *iPtr, *oPtr, pixel;
  119.   int count;
  120.  
  121.   if ((image->type & 0xFF00) == 0x0100)  /* RLE image */
  122.     {
  123.       fseek(image->file, image->rowStart[y+z*image->sizeY], SEEK_SET);
  124.       fread(image->tmp[0], 1, (unsigned int)image->rowSize[y+z*image->sizeY],
  125.         image->file);
  126.  
  127.       iPtr = image->tmp[0];
  128.       oPtr = buf;
  129.       while (1) 
  130.     {
  131.       pixel = *iPtr++;
  132.       count = (int)(pixel & 0x7F);
  133.       if (!count)
  134.         return;
  135.       if (pixel & 0x80) 
  136.         {
  137.           while (count--) 
  138.         {
  139.           *oPtr++ = *iPtr++;
  140.         }
  141.         } 
  142.       else 
  143.         {
  144.           pixel = *iPtr++;
  145.           while (count--) 
  146.         {
  147.           *oPtr++ = pixel;
  148.         }
  149.         }
  150.     }
  151.     }
  152.   else /* verbatim image */
  153.     {
  154.       fseek(image->file, 512+(y*image->sizeX)+(z*image->sizeX*image->sizeY),
  155.         SEEK_SET);
  156.       fread(buf, 1, image->sizeX, image->file);
  157.     }
  158. }
  159.  
  160. static void ImageGetRawData( Image *image, char *data)
  161. {
  162.   int i, j, k;
  163.   int remain;
  164.  
  165.   switch ( image->sizeZ )
  166.     {
  167.     case 1:
  168.       remain = image->sizeX % 4;
  169.       break;
  170.     case 2:
  171.       remain = image->sizeX % 2;
  172.       break;
  173.     case 3:
  174.       remain = (image->sizeX * 3) & 0x3;
  175.       if (remain)
  176.     remain = 4 - remain;
  177.       break;
  178.     case 4:
  179.       remain = 0;
  180.       break;
  181.     }
  182.  
  183.   for (i = 0; i < image->sizeY; i++) 
  184.     {
  185.       for ( k = 0; k < image->sizeZ ; k++ )
  186.     ImageGetRow(image, image->tmp[k+1], i, k);
  187.       for (j = 0; j < image->sizeX; j++) 
  188.     for ( k = 1; k <= image->sizeZ ; k++ )
  189.       *data++ = *(image->tmp[k] + j);
  190.       data += remain;
  191.     }
  192. }
  193.  
  194. IMAGE *ImageLoad(char *fileName)
  195. {
  196.   Image *image;
  197.   IMAGE *final;
  198.   int sx;
  199.  
  200.   image = ImageOpen(fileName);
  201.  
  202.   final = (IMAGE *)malloc(sizeof(IMAGE));
  203.   if (final == NULL) 
  204.     {
  205.       fprintf(stderr, "Out of memory!\n");
  206.       exit(-1);
  207.     }
  208.   final->imagic = image->imagic;
  209.   final->type = image->type;
  210.   final->dim = image->dim;
  211.   final->sizeX = image->sizeX; 
  212.   final->sizeY = image->sizeY;
  213.   final->sizeZ = image->sizeZ;
  214.  
  215.   /* 
  216.    * Round up so rows are long-word aligned 
  217.    */
  218.   sx = ( (image->sizeX) * (image->sizeZ) + 3) >> 2;
  219.  
  220.   final->data 
  221.     = (unsigned char *)malloc( sx * image->sizeY * sizeof(unsigned int));
  222.  
  223.   if (final->data == NULL) 
  224.     {
  225.       fprintf(stderr, "Out of memory!\n");
  226.       exit(-1);
  227.     }
  228.  
  229.   ImageGetRawData(image, final->data);
  230.   ImageClose(image);
  231.   return final;
  232. }
  233.